/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2009, Around(J2)ME				                                 **
 **   All rights reserved.                                                   **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the New BSD License which accompanies this    			 **
 **   distribution.											                 **
 **   A copy is found in the textfile LICENSE.txt							 **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Main developers:                                                       **
 **     Juri Strumpflohner		http://blog.js-development.com	             **
 **		Matthias Braunhofer		http://matthias.jimdo.com                    **
 **                                                                          **
 **  **********************************************************************  */

package com.aroundj2me.controller;

import java.util.Stack;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;

import com.aroundj2me.model.BackCommand;
import com.aroundj2me.utility.AlertCreator;
/**
 * This class is responsible for managing everything that is
 * displayed on the display of the mobile device. The "screens"
 * displayed are managed with a Stack data-structure.
 * The class is a "Singleton"
 *
 */
public class ScreenController {
	private static ScreenController instance = null;
	private Display display;
	private Stack screens;
	
	private ScreenController(){
		screens = new Stack();
	}
	
	public static ScreenController getInstance(){
		if(instance == null)
			instance = new ScreenController();
		return instance;
	}
	
	/**
	 * Destroyes the instance of this singleton
	 * ScreenController class
	 *
	 */
	public static void destroyInstance(){
		instance = null;
	}
	
	/**
	 * Displayes an object of type Displayable on the device Display and
	 * puts the current displayed screen on the stack
	 * @param d Displayable object
	 */
	public void display(Displayable d){
		if(!skip(this.display.getCurrent()) && !skip(d)){
			
			screens.push(this.display.getCurrent());
		}
		this.display.setCurrent(d);
	}
	
	/**
	 * Automatically adds a back command to the given {@link Displayable}
	 * @param d the {@link Displayable} to which to add the back command
	 * @param autoHookBackCommand
	 */
	public void display(Displayable d, boolean autoHookBackCommand){
		Command backCommand = new BackCommand();
		d.addCommand(backCommand);
		display(d);
	}

	/**
	 * retrieves the last screen on top of the
	 * stack after sleeping for some time
	 *
	 */
	public void lastWithDelay(){
		sleep();
		last();
	}
	
	/**
	 * retrieves the last screen from the top of
	 * the stack and displayes it
	 *
	 */
	public void last(){
		Displayable prevScreen = null;
		if(!screens.isEmpty()){
			prevScreen = (Displayable)screens.pop();
			this.display.setCurrent(prevScreen);
		}
	}
	
	/**
	 * Proofs if the Displayable d should be put on the stack or not
	 * Usually "Alerts" shouldn't be pushed on the stack
	 */
	private boolean skip(Displayable d){
		boolean tmp = d instanceof Alert;
		return tmp;
	}
	
	/**
	 * Sleeps some time
	 */
	private void sleep(){
		try {
			Thread.sleep(AlertCreator.DELAY);
		} catch (InterruptedException e) {
			System.out.println(e.getMessage());
		}finally{
		}
	}
	
	/*
	 * Getters and Setters
	 */
	
	public void setDisplay(Display d){
		this.display = d;
	}
}
